package Network;

use strict;
use lib ".";
use Logger;

use Data::Dumper;

use NetAddr::IP;

use Segment;
use Utils;

use Class::DBI::AbstractSearch;			# for search_where
#use base qw (NetworkDB);

#__PACKAGE__->set_up_table('networks');				# table name
#__PACKAGE__->has_many(segments => 'Segment');		# subclass name

sub IP2Plug {
	my $self = shift; my ($IP) = @_;	# operation 1 = activate, operation 0 = deactivate
	my $plug;

	my $technik_navod = 'kontaktujte technika';

	my $retval = Network->IP2MAC($IP);
	Logger->write(__PACKAGE__." IP2MAC($IP) => $retval");

	if (!$retval) {
		Logger->write(__PACKAGE__." Arpwatch error retval = $retval");
		return { errmsg => "CHYBA: Vasa IP adresa $IP nema zaznam v databaze Arpwatch, $technik_navod." };
	}

	my $segment = $self->IP2Segment($IP);
	if (!$segment) {
		return { errmsg => "CHYBA: Vasa IP adresa $IP nepatri do rozsahov IP adries definovanych v systeme LANmgmt. Pre vyriesenie problemu $technik_navod." };
	}

	if (Utils::isMACvalid($retval)) {
		my $MAC = $retval;
		my $addr_ident = "Vasa IP adresa: $IP, Vasa fyzicka (MAC) adresa: $MAC";
		if ($self->verify_address_assignment($MAC, $IP)) {
			$plug = $segment->MAC2Plug($MAC);
			if (!$plug) {
				return { errmsg => "CHYBA: Vasu zasuvku sa nepodarilo lokalizovat. Uistite sa, ci sa pripajate k oficialnej sieti a ak ano, $technik_navod. $addr_ident." };
			} elsif ($plug->is_vlan_trunk) {
				return { errmsg => "CHYBA: Pripajate sa z neregistrovanej zasuvky. $addr_ident." };
			} else {
				return $plug;		# !!! JEDINA SPRAVNA ODPOVED !!!
			}
		} else {
				return { errmsg => "CHYBA: Nemate spravnu IP adresu. Skontrolujte sulad nastaveni IP Vasho systemu s pokynmi Vasho spravcu siete. Ak si s tym neviete poradit, $technik_navod. $addr_ident." };
		}
	}
        return { errmsg => "CHYBA: Vasu IP adresu $IP sa nepodarilo v sieti lokalizovat, $technik_navod." };
}

sub IP2MAC {
        my $self = shift;
        my $IP = shift;

	Logger->write(__PACKAGE__." before IP -> segment");
	my $segment = $self->IP2Segment($IP);
	Logger->write(__PACKAGE__." after IP -> segment");
        if (!$segment) {
		Logger->write(__PACKAGE__."segment = -1 :-(");
                return -1;
        }

	Logger->write(__PACKAGE__." before Segment::ARPgetMAC($IP)");
        my $MAC = $segment->ARPgetMAC($IP);
	Logger->write(__PACKAGE__." after Segment::ARPgetMAC($IP) => $MAC");
        if (defined $MAC && $MAC) {
                return $MAC;
        } else {
                return 0;
        }
}


sub IP2Segment {		# every IP belongs to 0 or 1 segments
	my $self = shift;
	my $IP = NetAddr::IP->new(shift);
	Logger->write(__PACKAGE__." IP2Segment($IP) before db retrieval");
	my $segment = Segment->search_where(
		subnet => { '>>', $IP->addr }
	)->next;		# return data of the segment, which contains IP address given as input
	Logger->write(__PACKAGE__." IP2Segment($IP) after db retrieval");
	if ($segment) {
		return $segment;
	} else {
		return 0;
	}
}

sub verify_address_assignment {         # zisti platnost priradenia MAC/IP podla databazy a dhcpd.leases
        my $self = shift;
        my ($MAC, $IP) = @_;
	my $segment = $self->IP2Segment($IP);
	Logger->write(__PACKAGE__." verify_address_assignment($MAC, $IP)::IP2Segment($IP)::".$segment->segmentid);
        my (@MACs) = $segment->dhcp_serverid->IP2MAC($IP); # zistenie MAC adresy databazy, pripadne dhcpd.leases
	Logger->write(__PACKAGE__." verify_address_assignment($MAC, $IP)::DHCPserver::IP2MAC($IP)::".join ' ',@MACs);
        if ($#MACs > -1 && $MACs[0]) {  # ak ma IP aspon jednu MAC v DHCP (viac ako jednu by mat nemala)
                foreach (@MACs) {       # tento cyklus by to malo teda prejst len raz
                        if ($MAC eq $_) {       # ak sa zhoduju udaje z ARP a DHCP
                                return 1;
                        }
                }
        }
        return 0;       # default: priradenie MAC-IP sa nenaslo
}

# TODO: implementovat funkciu, ktora zisti riadne, alternativne aj historicke priradenia MAC/IP (pripadne aj lokalizacie), pricom cerpat udaje bude z databazy LANmgmt, databazy arpwatch, dhcpd.leases, dalsich logov vzniknutych monitorovanim siete a zaznamenavanim adries a ich lokalizacii - ak nebudu postacovat udaje z HDSW ziskane z LANmgmt
#sub alternative_address_assignments {
#        my $self = shift;
#        my (@addresses) = @_;
#        foreach my $address (@addresses) { }
#}


1;
